package org.qing.freepx.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.qing.config.db.DbManager;
import org.qing.freepx.entity.IPProxy;
import org.qing.freepx.service.IpWebProxyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class IpWebProxyServiceimpl implements IpWebProxyService {
	
	@Autowired
	private DbManager dbManager;
	
	@Override
	public List<IPProxy> getList() {
		return dbManager.getAllFromDatabase(IPProxy.class);
	}
	
	@Override
	public int add(IPProxy iPProxy) {
		return dbManager.writeToDatabase(iPProxy.getIp(), iPProxy, IPProxy.class, true);
	}

	@Override
	public IPProxy getIPProxy(String ip) {
		return dbManager.readFromDatabase(ip, IPProxy.class);
	}
	
	@Override
	public int delete(String ip) {
		return dbManager.deleteFromDatabase(ip);
	}

	@Override
	public List<IPProxy> getIPProxyList() {
		List<IPProxy> ips = new ArrayList<>();
		ExecutorService exe = Executors.newFixedThreadPool(10);
		try {
			Document doc = Jsoup.connect("http://www.89ip.cn/tqdl.html?api=1&num=500&port=&address=&isp=").get();
			log.debug("doc.text():{}", doc.text());
			String[] ipprot = doc.text().split(" ");
			CountStatus countStatus = new CountStatus();
			log.debug("START总次数:{},成功次数:{},失败次数:{}", countStatus.getTotal(), countStatus.getSuc(), countStatus.getFail());
			for (int i=0;i<ipprot.length-2;i++) {
				String map = ipprot[i];
				log.debug("map:{}",map);
				String maps[] = map.split(":");
				IPProxy iPProxy = new IPProxy();
				iPProxy.setIp(maps[0]);
				iPProxy.setPort(Integer.valueOf(maps[1]));
				iPProxy.setProtocol("http");
				iPProxy.setUpdateTime(new Date());
				iPProxy.setCreateTime(new Date());
				checkIp a = new checkIp(ips, iPProxy,dbManager,countStatus);
				exe.execute(a);
			}
			exe.shutdown();
			log.debug("END总次数:{},成功次数:{},失败次数:{}", countStatus.getTotal(), countStatus.getSuc(), countStatus.getFail());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ips;
	}

}

@Data
class CountStatus{
	private int suc = 0;
	private int total = 0;
	private int fail = 0;
	
	public synchronized int incSuc() {
		suc = suc+1;
		return suc;
	}
	
	public synchronized int incTotal() {
		total = total+1;
		return total;
	}

	public synchronized int incFail() {
		fail = fail+1;
		return fail;
	}
	
}

@Slf4j
class checkIp implements Runnable {
	
	private List<IPProxy> ips;
	private IPProxy iPProxy;
	private DbManager dbManager;
	private CountStatus countStatus;

	public checkIp(List<IPProxy> ips, IPProxy iPProxy, DbManager dbManager,CountStatus countStatus) {
		super();
		this.ips = ips;
		this.iPProxy = iPProxy;
		this.dbManager = dbManager;
		this.countStatus = countStatus;
	}

	public void run() {
		Random uaRandom = new Random();
		String[] ua = { "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
				"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586",
				"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
				"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
				"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)",
				"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.3 Safari/537.36",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.277.400 QQBrowser/9.4.7658.400",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 UBrowser/5.6.12150.8 Safari/537.36",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 TheWorld 7",
				"Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/60.0" };
		int uaIndex = uaRandom.nextInt(14);
		Map<String, String> map = new HashMap<String, String>();
		map.put("waybillNo","DD1838768852");
		try {
			countStatus.incTotal();
			long a = System.currentTimeMillis();
			// 爬取的目标网站，url记得换下。。。！！！
			Document doc = Jsoup.connect("http://trace.yto.net.cn:8022/TraceSimple.aspx").timeout(5000)
					.proxy(iPProxy.getIp(), iPProxy.getPort()).data(map).ignoreContentType(true).userAgent(ua[uaIndex])
					.header("referer", "http://trace.yto.net.cn:8022/gw/index/index.html")// 这个来源记得换..
					.post();
			countStatus.incSuc();
			log.debug("ip:{},port:{},time:{},doc.text():{}", iPProxy.getIp(), iPProxy.getPort(),
					(System.currentTimeMillis() - a), doc.text());
			ips.add(iPProxy);
			dbManager.writeToDatabase(iPProxy.getIp(), iPProxy, IPProxy.class, true);
			log.debug("总次数:{},成功次数:{},失败次数:{}", countStatus.getTotal(), countStatus.getSuc(), countStatus.getFail());
		} catch (IOException e) {
			countStatus.incFail();
			log.error(e.getMessage());
			if(dbManager.readFromDatabase(iPProxy.getIp(), IPProxy.class)!=null) {
				dbManager.deleteFromDatabase(iPProxy.getIp());
			}
			log.debug("总次数:{},成功次数:{},失败次数:{}", countStatus.getTotal(), countStatus.getSuc(), countStatus.getFail());
		}
	}

}
